/**
 *    @file       czlib.cpp
 *
 *    @brief      
 *    @details
 *
 *    @version    1.0
 *    @date       01/25/2014 10:15:53 PM
 *
 *    @author     Theophilus (), wangtf418@gmail.com 
 */
#include <zlib.h>
#include "czlib.h"

//class czlib//////////////////////////////////
czlib::czlib()
{

}

czlib::~czlib()
{

}

bf_int_t czlib::compress(const bf_uchar_t *src, bf_ulong_t srclen, bf_uchar_t *dest, bf_ulong_t &destlen)
{
	if (!src || srclen == 0 || !dest || destlen <= 12)
	{
		return BF_ERROR;
	}
	bf_int_t ret = ::compress(dest, &destlen, src, srclen);
	if (ret != Z_OK)
	{
		return BF_ERROR;
	}
	return BF_OK;
}

bf_int_t czlib::uncompress(const bf_uchar_t *src, bf_ulong_t srclen, bf_uchar_t *dest, bf_ulong_t &destlen)
{
	if (!src || srclen == 0 || !dest || destlen < srclen)
	{
		return BF_ERROR;
	}
	bf_int_t ret = ::uncompress(dest, &destlen, src, srclen);
	if (ret != Z_OK)
	{
		return BF_ERROR;
	}
	return BF_OK;
}


//class czlib_compress////////////////////////////
czlib_compress::czlib_compress()
{

}

czlib_compress::~czlib_compress()
{

}

bf_int_t czlib_compress::compress(const bf_uchar_t *src, bf_ulong_t srclen)
{
	if (!src || srclen == 0)
	{
		return BF_ERROR;
	}
	m_buf.clear();
	bf_size_t maxlen = (bf_size_t)((srclen + 12) * 1.1) + 1;
	m_buf.resize(maxlen);
	bf_uchar_t *dest = (bf_uchar_t*)m_buf.c_str();
	bf_ulong_t destlen = maxlen;
	bf_int_t ret = ::compress(dest, &destlen, src, srclen);
	if (ret != Z_OK)
	{
		return BF_ERROR;
	}
	m_buf.resize(destlen);
	return BF_OK;
}

//class czlib_uncompress//////////////////////////
czlib_uncompress::czlib_uncompress()
{

}

czlib_uncompress::~czlib_uncompress()
{

}

bf_int_t czlib_uncompress::uncompress(const bf_uchar_t *src, bf_ulong_t srclen, bf_ulong_t destlen /* = 0 */)
{
	if (!src || srclen == 0)
	{
		return BF_ERROR;
	}
	m_buf.clear();
	if (destlen == 0)
	{
		m_buf.resize((1024 > srclen * 4)? 1024:srclen * 4);
	}
	else
	{
		m_buf.resize(destlen);
	}
	
	bf_int_t ret = BF_OK;
	while (true)
	{
		bf_uchar_t *dest = (bf_uchar_t*)m_buf.c_str();
		bf_ulong_t destlen = m_buf.length();
		ret = ::uncompress(dest, &destlen, src, srclen);
		if (ret == Z_BUF_ERROR)
		{
			m_buf.resize(m_buf.length() * 2);
			continue;
		}

		if (ret == Z_OK)
		{
			m_buf.resize(destlen);
		}
		else
		{
			ret = BF_ERROR;
		}
		break;
	}
	return ret;
}


